package com.jiakai.cashinterfacemucon.service.impl;

import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.jiakai.cashinterfacemucon.dao.LogMapper;
import com.jiakai.cashinterfacemucon.dao.ProductMapper;
import com.jiakai.cashinterfacemucon.dto.*;
import com.jiakai.cashinterfacemucon.model.LogWithBLOBs;
import com.jiakai.cashinterfacemucon.model.Product;
import com.jiakai.cashinterfacemucon.service.SilverFamilyService;
import com.jiakai.cashinterfacemucon.utils.DateUtils;
import com.jiakai.cashinterfacemucon.utils.EmptyUtils;
import com.jiakai.cashinterfacemucon.utils.EncryptionUtils;
import com.jiakai.cashinterfacemucon.vo.*;
import com.lishunyi.result.VO.ResultVO;
import com.lishunyi.result.utils.ResultUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Service
@Transactional
public class SilverFamilyServiceImpl implements SilverFamilyService {

    @Autowired
    private ProductMapper productMapper;
    @Autowired
    private LogMapper logMapper;

    private static Gson gson = new Gson();

    private static org.tempuri.Service service = new org.tempuri.Service();

    // 银科用户名
    @Value("${clota.merchantCode}")
    private String merchantCode;
    // 银科密码
    @Value("${clota.otaKey}")
    private String key;

    private String signature;

    @Override
    public Integer getProducts(GetProductsDto dto) {
        // 接口调用时间
        Date ptime = new Date();
        String parameters = gson.toJson(dto);
        // 计算签名的body
        String body = merchantCode + key + parameters;
        // 计算签名
        signature = EncryptionUtils.getSig(body);
        // 调用第三方接口
        String strReturn = null;
        try {
            strReturn= service.getServiceSoap().getProducts(merchantCode, parameters, signature);
        }catch (Exception e){
            return null;
        }finally {
            // 记录
            LogWithBLOBs logs = new LogWithBLOBs();
            logs.setApiName("GetProduct");
            logs.setCreateTime(ptime);
            logs.setOutData(parameters);
            logs.setInData(strReturn);
            logMapper.insert(logs);
        }
        ResultDto resultDto = gson.fromJson(strReturn,ResultDto.class);
        if (resultDto.getTrue()&&resultDto.getResultCode().equals("00")){
            String resultJson = resultDto.getResultJson();
            JsonArray array = gson.fromJson(resultJson,JsonArray.class);
            List<Product> products = new ArrayList<>();
            for (int i=0;i<array.size();i++){
                Product p;
                p = gson.fromJson(array.get(i),Product.class);
                p.setProductType(dto.getType());
                p.setParkCode(dto.getParkCode());
                p.setCreateTime(ptime);
                products.add(p);
            }
            int count = 0;
            for (Product p : products){
                if (productMapper.selectByPrimaryKey(p.getProductId())==null) {
                    count+=productMapper.insert(p);
                } else {
                    count+=productMapper.updateByPrimaryKey(p);
                }
            }
            return count;
        }
        return null;
    }

    @Override
    public ResultVO orderOccupies(OrderOccupiesVO vo) {
        if (vo == null){
            return ResultUtils.error(999,"参数不能为空");
        }
        // 转化为对象实体
        List<DetailVO> detailsVO = vo.getDetails();
        System.out.println(detailsVO);
        // 取出order
        OrderVO orderVO = vo.getOrder();
//        System.out.println(orderVO);
        // 取出details
        List<DetailDto> detailDtos = new ArrayList<>();
        // details转化
        for (DetailVO detailVO:detailsVO){
            DetailDto detailDto = gson.fromJson(gson.toJson(detailVO),DetailDto.class);
            detailDtos.add(detailDto);
        }
        // order转化
        OrderDto orderDto = gson.fromJson(gson.toJson(orderVO),OrderDto.class);
        // 新建给银科的对象
        OrderOccupiesDto dto = new OrderOccupiesDto();
        // 将传入信息序列化并写入传出对象
        dto.setDetails(gson.toJson(detailDtos));
        dto.setOrderDto(gson.toJson(orderDto));
        // 当前时间
        Date ptime = new Date();
        // 传出对象设置时间
        dto.setPtime(DateUtils.formatToDateTime(ptime));
        // 传出对象序列化
        String postOrder = gson.toJson(dto);
        // 计算签名的body
        String body = merchantCode + key +postOrder;
        // 计算签名
        signature = EncryptionUtils.getSig(body);
        // 调用银科接口
        String strReturn = null;
        try {
            strReturn = service.getServiceSoap().orderOccupies(merchantCode, postOrder, signature);
//            strReturn = "Test Ok";
        }
        catch (Exception e){
            e.printStackTrace();
            return ResultUtils.error(999,"第三方连接失败");
        }finally {
            // 创建Log并赋值
            LogWithBLOBs logs = new LogWithBLOBs();
            // 目前使用自增id的算法
            logs.setApiName("OrderOccupies");
            logs.setCreateTime(ptime);
            logs.setOutData(postOrder);
            logs.setInData(strReturn);
            //TODO 低效 消息队列解耦
            // 调用过程录入logs
            //        rabbitTemplate.convertAndSend("log",logs);
            // 使用直接写入数据库的方法
            logMapper.insert(logs);

        }
        ResultDto result = gson.fromJson(strReturn,ResultDto.class);

        // 返回调用失败
        if (result.getTrue().equals("false")){
            //TODO 调用失败
            return ResultUtils.error(Integer.valueOf(result.getResultCode()),result.getResultMsg());
        }

        // 返回调用成功 执行失败
        if (!result.getResultCode().equals("00")){
            //TODO 调用成功 第三方执行失败
            return ResultUtils.error(Integer.valueOf(result.getResultCode()),result.getResultMsg());
        }

        // 调用成功
        return ResultUtils.success();
    }

    @Override
    public ResultVO orderRelease(String orderNo) {
        if (EmptyUtils.isEmpty(orderNo)){
            return ResultUtils.error(999,"订单号不能为空");
        }

        // 调用接口的时间
        Date ptime = new Date();
        OrderReleaseDto dto = new OrderReleaseDto();
        dto.setOrderNo(orderNo);
        String parameters = gson.toJson(dto,OrderReleaseDto.class);
        // 需要传递的订单号
        String otaOrderNo = orderNo;
        // 计算签名的body
        String body = merchantCode + key +otaOrderNo + parameters;
        // 计算签名
        signature = EncryptionUtils.getSig(body);
        // 调用接口获取返回值
        String strReturn = null;
        try {
            strReturn = service.getServiceSoap().orderRelease(merchantCode, otaOrderNo, parameters, signature);
        }catch (Exception e){
            e.printStackTrace();
            return ResultUtils.error(999,"第三方连接失败");
        }finally {
            // 创建Log并赋值
            LogWithBLOBs logs = new LogWithBLOBs();
//        logs.setId(IDGenerator.getMeUUID());
            logs.setApiName("OrderRelease");
            logs.setCreateTime(ptime);
            logs.setOutData(gson.toJson(dto));
            logs.setInData(strReturn);
            //TODO 低效 消息队列解耦
            // 调用过程录入logs
//        rabbitTemplate.convertAndSend("log",logs);
            // 直接调用数据库写入方法
            logMapper.insert(logs);
        }
        // 转换成json以备调用
        ResultDto result = gson.fromJson(strReturn,ResultDto.class);

        //TODO 调用不成功
        if (result.getTrue().equals("false")){
            return ResultUtils.error(Integer.valueOf(result.getResultCode()),result.getResultMsg());
        }
        //TODO 调用成功 释放失败 ? 原因未知?
        if (!result.getResultCode().equals("00")){
            return ResultUtils.error(Integer.valueOf(result.getResultCode()),result.getResultMsg());
        }
        // 调用成功
        return ResultUtils.success();
    }

    @Override
    public ResultVO orderFinish(String orderNo) {
        if (EmptyUtils.isEmpty(orderNo)){
            return ResultUtils.error(999,"订单号不能为空");
        }
        // 调用接口的时间
        Date ptime = new Date();
        // 传递的json参数
        OrderFinishDto dto = new OrderFinishDto();
        dto.setOtaOrderNo(orderNo);
        String parameters = gson.toJson(dto,OrderFinishDto.class);
        // 短信发送标识
        Integer platformSend = dto.getPlatformSend();
        // 需要传递的订单号
        String otaOrderNo = orderNo;
        // 计算签名的body
        String body = merchantCode + key + otaOrderNo + platformSend + parameters;
        // 计算签名
        signature = EncryptionUtils.getSig(body);
        String strReturn = null;
        try {
            strReturn = service.getServiceSoap().orderFinish(merchantCode, otaOrderNo, platformSend, parameters, signature);
        }catch (Exception e){
            e.printStackTrace();
            return ResultUtils.error(999,"第三方连接失败");
        }finally {
            // 创建Log并赋值
            LogWithBLOBs logs = new LogWithBLOBs();
            logs.setApiName("OrderFinish");
            logs.setCreateTime(ptime);
            logs.setOutData(gson.toJson(dto));
            logs.setInData(strReturn);
            //TODO 低效 消息队列解耦
            // 调用过程录入logs
//        rabbitTemplate.convertAndSend("log",logs);
            logMapper.insert(logs);
        }
        ResultDto result = gson.fromJson(strReturn,ResultDto.class);
        //TODO 调用不成功
        if (result.getTrue().equals("false")){
            return ResultUtils.error(Integer.valueOf(result.getResultCode()),result.getResultMsg());
        }
        //TODO 调用成功 释放失败 ? 原因未知?
        if (!result.getResultCode().equals("00")){
            return ResultUtils.error(Integer.valueOf(result.getResultCode()),result.getResultMsg());
        }
        // 读取ResultJson
        String strEcodes = result.getResultJson();
        // 转化为数组 并求其长度
        JsonArray array = gson.fromJson(strEcodes,JsonArray.class);
        int len = array.size();
        // 将数组的键值对存入到list中
        List<EcodeFinishVO> ecodes = new ArrayList<>();
        for (int i = 0;i<len;i++){
            JsonElement element = array.get(i);
            EcodeFinishVO ecode = gson.fromJson(element,EcodeFinishVO.class);
            ecodes.add(ecode);
        }
        //TODO 将订单输入数据库
        //TODO 低效 消息队列解耦
        // 订单写入
        //TODO 订单明细查询并修改 明细状态 写入ecode
        // 返回集合
        return ResultUtils.success(ecodes);
    }

    @Override
    public ResultVO orderChange(OrderChangeVO vo) {
        if (null == vo || null == vo.getOrder() || null == vo.getDetails()){
            return ResultUtils.error(999,"参数不能为空");
        }
        // 调用接口的时间
        Date ptime = new Date();
        // 将传入的订单对象转化成字符串存入
        OrderChangeDto dto = new OrderChangeDto();
        List<FixDetailVO> detailsVO = vo.getDetails();
        FixOrderVO orderVO = vo.getOrder();
        // 转入对应的对象里
        // details vo -> dto
        List<FixDetailDto> detailsDto = new ArrayList<>();
        for (FixDetailVO detailVO : detailsVO){
            FixDetailDto detailDto = gson.fromJson(gson.toJson(detailVO),FixDetailDto.class);
//            FixDetailDto detailDto = JSON.parseObject(gson.toJson(detailVO),FixDetailDto.class);
            detailsDto.add(detailDto);
        }
        // order vo -> dto
        FixOrderDto orderDto = gson.fromJson(gson.toJson(orderVO),FixOrderDto.class);
//        FixOrderDto orderDto = JSON.parseObject(gson.toJson(orderVO),FixOrderDto.class);
        // count vo -> dto
//        dto.setCount(vo.getCount());
        // dto -> str
        String strDetails = gson.toJson(detailsDto);
        String strOrder = gson.toJson(orderDto);
        // 写入dto
        dto.setStrOrder(strOrder);
        dto.setStrDetails(strDetails);
        dto.setPtime(DateUtils.formatToDateTime(ptime));
        // 传递的json参数
        String postOrder = gson.toJson(dto,OrderChangeDto.class);
        System.out.println(postOrder);
        // 计算签名的body
        String body = merchantCode + key + postOrder ;
        // 计算签名
        signature = EncryptionUtils.getSig(body);
        String strReturn = null;
        try {
            // 调用接口并接收返回字符串
            strReturn = service.getServiceSoap().changeOrderEdit(merchantCode,postOrder,signature);
        }catch (Exception e){
            e.printStackTrace();
            return ResultUtils.error(999,"第三方连接失败");
        }finally {
            // 创建Log并赋值
            LogWithBLOBs logs = new LogWithBLOBs();
            logs.setApiName("OrderChange");
            logs.setCreateTime(ptime);
            logs.setOutData(gson.toJson(dto));
            logs.setInData(strReturn);
            //TODO 低效 消息队列解耦
            // 调用过程录入logs
//        rabbitTemplate.convertAndSend("log",logs);
            logMapper.insert(logs);
        }
        // 将返回值转化为json对象来取值
        ResultDto result = gson.fromJson(strReturn,ResultDto.class);
        //TODO 调用不成功
        if (result.getTrue().equals("false")){
            return ResultUtils.error(Integer.valueOf(result.getResultCode()),result.getResultMsg());
        }
        //TODO 调用成功 释放失败 ? 原因未知?
        if (!result.getResultCode().equals("00")){
            return ResultUtils.error(Integer.valueOf(result.getResultCode()),result.getResultMsg());
        }
        // 调用成功
        return ResultUtils.success();
    }

    @Override
    public ResultDto orderNotice(String OrderID, String ECode, Integer OrderNum, String NoticeType, String signature) {
        // 如果什么都没有传入,那么什么也不会传出
        String body = OrderID + ECode + OrderNum + NoticeType;

        OrderNoticeDto notice = new OrderNoticeDto();
        notice.setOrderID(OrderID);
        notice.setEcode(ECode);
        notice.setOrderNum(OrderNum);
        notice.setNoticeType(NoticeType);
        notice.setSignature(signature);

        // 调用接口的时间
        Date ptime = new Date();
        // 创建备返回对象
        ResultDto resultDto = new ResultDto();

        try {
            // 判断参数为空
            body = notice.getOrderID() + notice.getEcode() + notice.getOrderNum() + notice.getNoticeType();
            if (EmptyUtils.isEmpty(notice.getOrderID(),notice.getEcode(),notice.getNoticeType())||notice.getOrderNum() == null){
                resultDto.setResultCode("01");
                throw new RuntimeException("参数不能为空");
            }
            // 判断签名为空
            if (signature == null || signature == ""){
                resultDto.setResultCode("01");
                throw new RuntimeException("签名不能为空");
            }
            // 判断签名正确性
            if (signature!=EncryptionUtils.getSig(body)){
                resultDto.setResultCode("01");
                throw new RuntimeException("签名失败");
            }

            if (signature == EncryptionUtils.getSig(body)){

            //TODO 查询订单号状态 核对景区串码 ---- 需要调用数据库查询
            //TODO 判断NoticeType 0:入园核销 1:退票核销 2:退票审核失败
            //TODO 根据判断执行执行成功者返回成功jsonObject

                //FIXME 模拟输出部分
                System.out.println(notice);

                resultDto.setResultCode("00");
                resultDto.setResultMsg("操作成功");
            }
        }catch (Exception e){
            resultDto.setResultMsg(e.getMessage());
        }finally {
            // 创建Log并赋值
            LogWithBLOBs logs = new LogWithBLOBs();
            logs.setApiName("NoticeOrder");
            logs.setCreateTime(ptime);
            logs.setInData(gson.toJson(notice));
            logs.setOutData(gson.toJson(resultDto));
            //TODO 低效 消息队列解耦
            // 调用过程录入logs
    //        rabbitTemplate.convertAndSend("log",logs);
            logMapper.insert(logs);
        }

        return resultDto;
    }


}
